
In this folder we show how to create a simple pipeline between
a parent process and its child process.

By "simple pipeline" we mean that the stdout of the parent is
connected to the stdin of the child. So whatever the parent
writes to its stdout shows up as input to the child's stdin.
We will also assume that the parent is reading data from its
stdin and that the child's stdout is inherited from the parent.
So we want to create something that looks like this.

             parent                       child
          +------------+              +------------+
          |            |     pipe     |            |
  stdin-->>0         1>>------------->>0         1>>--->stdout
          |            |              |            |
          |          2>>              |          2>>
          |            |              |            |
          |            |              |            |
          |            |              |            |
          +------------+              +------------+

A simple pipeline like this would represent two processes working
together to accomplish some task. Each process does only part of
the task. After the first process has done what it can to the
input data, it passes its results to the second process to do its
share of the processing. The final result is written to stdout by
the second process.

To set up this pipeline, we need to do two things, have the child
inherit its stdout from the parent, and then connect the parent's
stdout to the child's stdin.

Both of these steps are easy in Java 7, but the inheriting step
doesn't seem to work on Windows. See the file
   Java7_ParentChildPipeline.java.


In Java 6, the pipeline step is surprisingly easy. That is because
we can "get" the stdin stream of the child, and we can "set" the
parent's stdout to be that stream (what we cannot do is "set" any
of the child's streams). The line of code looks like this in the
parent process.

   System.setOut( new PrintStream( process.getOutputStream() ) );

Notice how, when we "get" the child's stdin stream, we call the
method getOutputStream(). Why do we call getOutputStream() when
we want to get an input stream? Because to the parent, the stream
it gets from the child looks like an output stream; the parent will
be "writing" to this stream to send data into the child. The name
of the "get" function is based on the point of view of the process
that is actually getting the stream, not the point of view of the
process where the stream is gotten from. See the following piece
of Javadoc
  http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#getOutputStream()
This is a source of endless confusion.

As in the previous folder, using Java 6 to get the child to inherit
the parent's stdout requires an awkward arrangement of new streams
in the parent process. Here is a diagram of what we must create in
Java 6.

             parent                         child
          +------------+                +------------+
          |            |      pipe      |            |
  stdin-->>0         1>>--------------->>0         1>>----+
          |            |                |            |    |
          |          2>>                |          2>>    |
          |            |                |            |    |
          |    pump    |                |            |    |
    +---->>4-->-->---3>>---+            |            |    |
    |     |            |   |            |            |    |
    |     +------------+   |            +------------+    |
    |                      |                              |
    |                      |                              |
    |                      +->parent's original stdout    |
    |                                                     |
    +------------<--------------<------------<------------+


Notice how, in this picture, the parent's stdout is redirected to the
child's stdin (that's the pipeline), but, in addition, the parent's
original stdout stream is saved (as 3) so that the "pump" can use it
when it pumps the child's stdout stream (from 4 to 3).

As in previous folders, there are three ways to implement the "pump".
  1) Read everything from the parent's stdin while writing it all to
     the next stage, then read everything out of the pipeline while
     sending it all to the parent's original stdout.
  2) Read each line from the parent's stdin and send that line to the
     next stage of the pipeline, read the resulting line right away
     from the end of the pipeline and send it to the parent's original
     stdout.
  3) Create a "pump" thread that, independently from the main() thread,
     reads from the child's stdout and writes to the parent's original
     stdout (while the main() thread reads from the parent's stdin and
     writes to the next stage).

See the following files. Be sure to correlate the code in those
files with the above diagram.
   Java6_ParentChildPipeline_ver1.java
   Java6_ParentChildPipeline_ver2.java
   Java6_ParentChildPipeline_ver3.java